﻿#include "PickedData.h"

// Qt
#include <QVector>

// VTK
#include <vtkUnstructuredGrid.h>
#include <vtkActor.h>
#include <vtkActor2D.h>
#include <vtkImageActor.h>
#include <vtkMapper.h>

// APP
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKKeyMouseStates.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"

// Global data
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"

// Data
#include "FITK_Component/FITKGeoCompOCC/FITKAbstractOCCModel.h"

// Graph
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActor.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActor2D.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKGraphActorImage.h"
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphObject3D.h"
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphActor.h"

// GUI
#include "GUIPickInfo.h"

namespace GraphData
{
    PickedData::PickedData(GUI::GUIPickInfoStru pickedInfo, vtkActor* pickedActor, int pickedIndex, double* pickedWorldPos) :
        m_pickedInfo(pickedInfo), m_pickedActor(pickedActor), m_pickedIndex(pickedIndex)
    {
        // 初始化鼠标操作方式。（点击）
        m_mouseOper = PickedMouseType::PickedMouseClick;

        if (pickedWorldPos)
        {
            m_pickedWorldPos[0] = pickedWorldPos[0];
            m_pickedWorldPos[1] = pickedWorldPos[1];
            m_pickedWorldPos[2] = pickedWorldPos[2];
        }

        // 初始化。
        init();
    }

    PickedData::PickedData(GUI::GUIPickInfoStru pickedInfo, vtkActor2D* pickedActor) :
        m_pickedInfo(pickedInfo), m_pickedActor2D(pickedActor)
    {
        // 初始化鼠标操作方式。（点击）
        m_mouseOper = PickedMouseType::PickedMouseClick;

        // 初始化。
        init2D();
    }

    PickedData::PickedData(GUI::GUIPickInfoStru pickedInfo, vtkImageActor* pickedActor) :
        m_pickedInfo(pickedInfo), m_pickedActorImg(pickedActor)
    {
        // 初始化鼠标操作方式。（点击）
        m_mouseOper = PickedMouseType::PickedMouseClick;

        // 初始化。
        initImage();
    }

    PickedData::PickedData(GUI::GUIPickInfoStru pickedInfo, vtkActor* pickedActor, vtkPlanes* pickPlanes) :
        m_pickedInfo(pickedInfo), m_pickedActor(pickedActor), m_pickPlanes(pickPlanes)
    {
        // 初始化鼠标操作方式。（框选）
        m_mouseOper = PickedMouseType::PickedMouseRubber;

        // 初始化。
        init();
    }

    PickedData::PickedData()
    {

    }

    PickedData::~PickedData()
    {
        // 析构前取消高亮状态。
        clearHighlight();
    }

    void PickedData::saveKeyFlags(Qt::Key qKey, bool flag)
    {
        m_keyFlagsHash[qKey] = flag;
    }

    PickedData* PickedData::getCopy()
    {
        if (m_needToCal || !m_isValid)
        {
            return nullptr;
        }

        PickedData* data = new PickedData;
        data->m_type = m_type;
        data->m_dataObjId = m_dataObjId;

        data->m_ids = m_ids;
        data->m_graphObject = m_graphObject;
        data->m_keyFlagsHash = m_keyFlagsHash;

        data->m_pickedActor = m_pickedActor;
        data->m_pickedActor2D = m_pickedActor2D;
        data->m_pickedActorImg = m_pickedActorImg;
        data->m_pickedIndex = m_pickedIndex;
        data->m_pickedInfo = m_pickedInfo;

        return data;
    }

    void PickedData::sortIds()
    {
        if (!m_ids.isEmpty())
        {
            std::sort(m_ids.begin(), m_ids.end());
        }
    }

    bool PickedData::isSameAs(PickedData* data, bool checkIds)
    {
        if (!data)
        {
            return false;
        }

        // 二者均为SEA节点数据并且SEA节点编号、类型、顺序均一致则视为相同数据。
        if (m_pickedInfo._pickObjType == GUI::GUIPickInfo::PickObjType::POBJDiscNode && 
            data->m_pickedInfo._pickObjType == GUI::GUIPickInfo::PickObjType::POBJDiscNode)
        {
            if (checkIds)
            {
                QList<Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode> outData = data->getPickedDiscNodes();
                QList<Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode> thisData = getPickedDiscNodes();

                if (outData.count() != thisData.count())
                {
                    return false;
                }

                for (int i = 0; i < outData.count(); i++)
                {
                    const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & iOutNode = outData[i];
                    const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & iThisNode = thisData[i];

                    if (iOutNode._id != iThisNode._id || iOutNode._type != iThisNode._type)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
        // 其他数据进行ID比较。
        else
        {
            if (data->m_type == m_type &&
                data->m_dataObjId == m_dataObjId)
            {
                // 比较拾取ID列表。
                if (checkIds)
                {
                    return data->m_ids == m_ids;
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        return false;
    }

    void PickedData::sort()
    {
        std::sort(m_ids.begin(), m_ids.end());
    }

    void PickedData::add(PickedData* data)
    {
        if (!data)
        {
            return;
        }

        // 合并普通数据。
        //@{
        // 首先进行排序，获取ID最大值。（最后一位ID）
        sort();
        data->sort();

        // 获取最大ID开数组存取存在标识。
        if (m_ids.count() && data->m_ids.count())
        {
            int nIdsMax = qMax(m_ids.last(), data->m_ids.last());
            QVector<int> idFlag(nIdsMax);
            idFlag.fill(-1);
            for (const int & id : m_ids)
            {
                idFlag[id - 1] = 1;
            }

            // 合并单元或节点ID。
            QHash<int, int> pickOther = data->getPickedOtherIDs();
            for (const int & id : data->m_ids)
            {
                if (idFlag[id - 1] == -1)
                {
                    m_ids.push_back(id);
                    m_otherIds.insert(id, pickOther.value(id));
                    idFlag[id - 1] = 1;
                }
            }
        }

        // 排序。
        sortIds();
        //@}

        // 特殊合并SEA节点。
        //@{
        // 在历史数据中去重。（无视节点类型，只查询节点ID）
        for (const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & ssNode : data->getPickedDiscNodes())
        {
            bool hasTheNode = false;
            for (const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & ssNodeHist : m_seaNodes)
            {
                if (ssNode._id == ssNodeHist._id)
                {
                    hasTheNode = true;
                    break;
                }
            }

            // 合并不重复节点。
            if (!hasTheNode)
            {
                m_seaNodes.push_back(ssNode);
            }
        }
        //@}

        // 额外拷贝后者键盘按下情况。
        m_keyFlagsHash = data->m_keyFlagsHash;

        // 合并后析构。
        delete data;
    }

    void PickedData::subtract(PickedData* data)
    {
        if (!data)
        {
            return;
        }

        // 去除普通数据。
        //@{
        // 首先进行排序，获取ID最大值。（最后一位ID）
        sort();
        data->sort();

        // 获取最大ID开数组存取存在标识。
        if (m_ids.count() && data->m_ids.count())
        {
            int nIdsMax = qMax(m_ids.last(), data->m_ids.last());
            QVector<int> idFlags(nIdsMax);
            idFlags.fill(-1);
            for (const int & id : m_ids)
            {
                idFlags[id - 1] = 1;
            }

            // 移除单元或节点ID。
            QHash<int, int> pickOtherData = data->getPickedOtherIDs();
            for (const int & id : data->m_ids)
            {
                if (idFlags[id - 1] == 1)
                {
                    idFlags[id - 1] = -1;
                }
            }

            m_ids.clear();
            m_otherIds.clear();
            for (int i = 0; i < idFlags.count(); i++)
            {
                int& idFlag = idFlags[i];
                if (idFlag == 1)
                {
                    m_ids.push_back(i + 1);
                    m_otherIds.insert(i + 1, m_otherIds.value(i + 1));
                }
            }
        }
        //@}
        
        // 特殊去除SEA节点。
        //@{
        // 在历史数据中去除。（无视节点类型，只查询节点ID）
        for (const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & ssNode : data->getPickedDiscNodes())
        {
            for (int i = 0; i < m_seaNodes.count(); i++)
            {
                const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & ssNodeHist = m_seaNodes[i];
                if (ssNode._id == ssNodeHist._id)
                {
                    m_seaNodes.removeAt(i);
                    break;
                }
            }
        }
        //@}

        // 合并后析构。
        delete data;
    }

    void PickedData::merge(PickedData* data)
    {
        if (!data)
        {
            return;
        }

        PickedMouseType mouseType = data->getPickedMouseType();
        switch (mouseType)
        {
        case GraphData::PickedMouseClick:
        {
            // 数据不相同则取消融合。
            if (!this->isSameAs(data))
            {
                return;
            }

            // 点选需要对数据融合方式进行判断。
            bool hasPicked = this->contains(data->getPickedActor(), data->getPickedIndex());

            // 拾取数据重叠则进行减选。
            if (hasPicked)
            {
                this->subtract(data);
            }
            // 拾取数据不重叠则进行增量拾取。
            else
            {
                this->add(data);
            }

            break;
        }
        case GraphData::PickedMouseRubber:
        {
            // 框选默认为增量融合。
            this->add(data);
            break;
        }
        case GraphData::PickedNoneType:
        default:
            return;
        }
    }

    void PickedData::init()
    {
        // 尝试转换为自定义Actor。
        FITKAcousticsVTKGraphActor* fActor = FITKAcousticsVTKGraphActor::SafeDownCast(m_pickedActor);
        if (!fActor)
        {
            return;
        }

        // 获取演员存储的可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj = fActor->getGraphObjectAs<Exchange::FITKAcousticsVTKGraphObject3D>();
        if (!obj)
        {
            return;
        }

        // 保存可视化对象。
        m_graphObject = obj;
        m_dataObjId = obj->getDataId();

        // 转换拾取对象类型。
        if (!initPickObjType())
        {
            return;
        }

        m_needToCal = true;
        m_isValid = true;
    }

    void PickedData::init2D()
    {
        // 尝试转换为自定义Actor。
        FITKGraphActor2D* fActor2D = FITKGraphActor2D::SafeDownCast(m_pickedActor2D);
        if (!fActor2D)
        {
            return;
        }

        // 获取演员存储的可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj = fActor2D->getGraphObjectAs<Exchange::FITKAcousticsVTKGraphObject3D>();
        if (!obj)
        {
            return;
        }

        // 保存可视化对象。
        m_graphObject = obj;
        m_dataObjId = obj->getDataId();

        // 转换拾取对象类型。
        if (!initPickObjType())
        {
            return;
        }

        m_needToCal = false;
        m_isValid = true;
    }

    void PickedData::initImage()
    {
        // 尝试转换为自定义Actor。
        FITKGraphActorImage* fActorImg = FITKGraphActorImage::SafeDownCast(m_pickedActorImg);
        if (!fActorImg)
        {
            return;
        }

        // 获取演员存储的可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj = fActorImg->getGraphObjectAs<Exchange::FITKAcousticsVTKGraphObject3D>();
        if (!obj)
        {
            return;
        }

        // 保存可视化对象。
        m_graphObject = obj;
        m_dataObjId = obj->getDataId();

        // 转换拾取对象类型。
        if (!initPickObjType())
        {
            return;
        }

        m_needToCal = false;
        m_isValid = true;
    }

    bool PickedData::initPickObjType()
    {
        m_type = PickedDataType::OtherPick;

        if (!m_graphObject)
        {
            return false;
        }

        Exchange::FITKAcousticsVTKCommons::AcousticsGraphInfo gInfo = m_graphObject->getGraphInfo();
        switch (gInfo.Type)
        {
        case Exchange::FITKAcousticsVTKCommons::ModelGraph:
        {
            // 尝试转换为自定义Actor。（模型拾取模式下三维演员一定不能为空，否则视为异常拾取数据）
            FITKAcousticsVTKGraphActor* fActor = FITKAcousticsVTKGraphActor::SafeDownCast(m_pickedActor);
            if (!fActor)
            {
                return false;
            }

            // 根据拾取演员类型获取几何拾取类型。
            ActorType aType = fActor->getActorType();
            switch (aType)
            {
            case ActorType::SolidActor:
                m_type = PickedDataType::GeoSolidPick;
                break;
            case ActorType::SurfaceActor:
                m_type = PickedDataType::GeoFacePick;
                break;
            case ActorType::EdgeActor:
                m_type = PickedDataType::GeoEdgePick;
                break;
            case ActorType::VertexActor:
                m_type = PickedDataType::GeoVertPick;
                break;
            default:
                return false;
            }

            break;
        }
        case Exchange::FITKAcousticsVTKCommons::MeshGraph:
            m_type = PickedDataType::MeshCellPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::DiscNodesGraph:
            m_type = PickedDataType::DiscNodePick;
            break;
        case Exchange::FITKAcousticsVTKCommons::BeamGraph:
            m_type = PickedDataType::SEABeamPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::ShellGraph:
            m_type = PickedDataType::SEAShellPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::CavityGraph:
            m_type = PickedDataType::SEACavityPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::SemiInfFluid:
            m_type = PickedDataType::SEASemiInfFluidPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::JunctionPoint:
            m_type = PickedDataType::JuncPointPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::JunctionLine:
            m_type = PickedDataType::JuncLinePick;
            break;
        case Exchange::FITKAcousticsVTKCommons::JunctionArea:
            m_type = PickedDataType::JuncAreaPick;
            break;      
        case Exchange::FITKAcousticsVTKCommons::LoadPointForceGraph:
            m_type = PickedDataType::LoadPointForcePick;
            break;
        case Exchange::FITKAcousticsVTKCommons::LoadPowerGraph:
            m_type = PickedDataType::LoadPowerPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::LoadConstraintGraph:
            m_type = PickedDataType::LoadConstraintPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::LoadImportGraph:
            m_type = PickedDataType::LoadImportPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::LoadExcForMomGraph:
            m_type = PickedDataType::LoadExcForMomPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::LoadMonopoleGraph:
            m_type = PickedDataType::LoadMonopolePick;
            break;
        case Exchange::FITKAcousticsVTKCommons::FEFaceGraph:
            m_type = PickedDataType::FEFacePick;
            break;
        case Exchange::FITKAcousticsVTKCommons::FEStructureShellGraph:
            m_type = PickedDataType::FEStructureShellPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::FEStructureBeamGraph:
            m_type = PickedDataType::FEStructureBeamPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::FEAcousticGraph:
            m_type = PickedDataType::FEAcousticPick;
            break;
        case Exchange::FITKAcousticsVTKCommons::SensorGraph:
            m_type = PickedDataType::FESensorPick;
            break;
        default:
            return false;
        }

        return true;
    }

    void PickedData::setPickedGraphObject(Exchange::FITKAcousticsVTKGraphObject3D* obj)
    {
        if (!obj)
        {
            return;
        }

        // 断开旧数据信号。
        if (m_graphObject)
        {
            disconnect(m_graphObject, &Exchange::FITKAcousticsVTKGraphObject3D::destroyed, this, &PickedData::slot_resetGraphObject);
        }

        // 保存数据，连接信号。
        m_graphObject = obj;
        connect(m_graphObject, &Exchange::FITKAcousticsVTKGraphObject3D::destroyed, this, &PickedData::slot_resetGraphObject, Qt::UniqueConnection);
    }

    void PickedData::slot_resetGraphObject()
    {
        m_graphObject = nullptr;
    }

    void PickedData::highlight()
    {
        if (!m_graphObject)
        {
            return;
        }

        switch (m_type)
        {
        case GraphData::OtherPick:
            break;
        case GraphData::GeoVertPick:
        {
            // 高亮几何点。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::ModelVertex, m_ids.toVector());
            break;
        }
        case GraphData::GeoEdgePick:
        {
            // 高亮几何线。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::ModelEdge, m_ids.toVector());
            break;
        }
        case GraphData::GeoFacePick:
        {
            // 高亮几何面。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::ModelFace, m_ids.toVector());
            break;
        }
        case GraphData::GeoSolidPick:
        {
            // 高亮几何体。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::ModelSolid, m_ids.toVector());
            break;
        }
        case GraphData::MeshCellPick:
        {
            // 高亮网格单元。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::MeshElement, m_ids.toVector());
            break;
        }
        case GraphData::DiscNodePick:
        {
            // 获取拾取SEA节点ID。
            QVector<int> ids;
            for (const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & ssNode : m_seaNodes)
            {
                ids.push_back(ssNode._id);
            }

            // SEA节点高亮。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::ModelVertex, ids);

            break;
        }    
        case GraphData::SEAShellPick:
        case GraphData::SEACavityPick:
        {
            // SEA合并数据子系统高亮。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::ModelVertex,
                QVector<int>() << m_dataObjId);

            break;
        }
        case GraphData::FEFacePick:
        case GraphData::FEStructureShellPick:
        case GraphData::FEStructureBeamPick:
        case GraphData::FEAcousticPick:
        {
            // FE合并数据子系统高亮。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::ModelVertex,
                QVector<int>() << m_dataObjId);

            break;
        }
        case GraphData::JuncLinePick:
        case GraphData::JuncAreaPick:
        {
            // SEA合并数据连接关系高亮。
            m_graphObject->advanceHighlight(Exchange::FITKAcousticsVTKCommons::ShapeType::Others,
                QVector<int>() << m_dataObjId);

            break;
        }
        case GraphData::SEABeamPick:
        case GraphData::SEASemiInfFluidPick:
        case GraphData::JuncPointPick:
        {
            // 整个数据拾取高亮整个对象。
            m_graphObject->highlight();
            break;
        }
        default:
            return;
        }
    }

    void PickedData::clearHighlight()
    {
        // 取消高亮。
        if (!m_graphObject)
        {
            return;
        }

        m_graphObject->disHighlight();
    }

    void PickedData::calculateFinsish()
    {
        m_needToCal = false;

        // m_mouseOper = PickedMouseType::PickedNoneType;
        // m_pickedIndex = -1;

        m_pickedWorldPos[0] = 0;
        m_pickedWorldPos[1] = 0;
        m_pickedWorldPos[2] = 0;
    }

    bool PickedData::needToCalculate()
    {
        return m_needToCal;
    }

    bool PickedData::isValid()
    {
        return m_isValid;
    }

    bool PickedData::isEmpty()
    {
        // 如果数据对象ID为空则一定为空拾取数据。
        if (m_dataObjId < 0)
        {
            return true;
        }

        // 非整个对象拾取模式下所有拾取数据列表均为空且拾取数据ID均为-1则视为空数据。
        switch (m_type)
        {
        case GraphData::GeoVertPick:
        case GraphData::GeoEdgePick:
        case GraphData::GeoFacePick:
        case GraphData::GeoSolidPick:
        case GraphData::MeshCellPick:
            return m_ids.isEmpty();
        case GraphData::DiscNodePick:
            return m_seaNodes.isEmpty();
        case GraphData::SEABeamPick:
        case GraphData::SEAShellPick:
        case GraphData::SEACavityPick:
        case GraphData::SEASemiInfFluidPick:
        case GraphData::JuncPointPick:
        case GraphData::JuncLinePick:
        case GraphData::JuncAreaPick:
            // 整个数据拾取存在数据ID则视为非空数据。
            return false;
        default:
            break;
        }

        return false;
    }

    bool PickedData::isFinished()
    {
        // 单选情况下数据不为空则直接视为拾取结束。
        if (m_pickedInfo._pickMethod == GUI::GUIPickInfo::PickMethod::PMSingle)
        {
            return true;
        }
        // 多选模式均通过键盘按下事件进行判断拾取结束。
        else
        {
            if (m_keyFlagsHash[Qt::Key::Key_Shift] && m_keyFlagsHash[Qt::Key::Key_Control])
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        return true;
    }

    bool PickedData::contains(vtkActor* actor, int index)
    {
        if (!actor || index < 0 || !m_graphObject)
        {
            return false;
        }

        // 首先判断是否为同一演员，参考点直接返回。
        if (actor != m_pickedActor)
        {
            return false;
        } 

        int id = -1;

        switch (m_type)
        {
        case GraphData::GeoVertPick:
        {
            id = m_graphObject->getShapeIdByVTKCellId(index, Exchange::FITKAcousticsVTKCommons::ShapeMeshAbsEnum::STA_VERTEX);
            return m_ids.contains(id);
        }
        case GraphData::GeoEdgePick:
        {
            id = m_graphObject->getShapeIdByVTKCellId(index, Exchange::FITKAcousticsVTKCommons::ShapeMeshAbsEnum::STA_EDGE);
            return m_ids.contains(id);
        }
        case GraphData::GeoFacePick:
        {
            id = m_graphObject->getShapeIdByVTKCellId(index, Exchange::FITKAcousticsVTKCommons::ShapeMeshAbsEnum::STA_FACE);
            return m_ids.contains(id);
        }
        case GraphData::GeoSolidPick:
        {
            id = m_graphObject->getShapeIdByVTKCellId(index, Exchange::FITKAcousticsVTKCommons::ShapeMeshAbsEnum::STA_SOLID);
            return m_ids.contains(id);
        }
        case GraphData::MeshCellPick:
        {
            id = m_graphObject->getShapeIdByVTKCellId(index, Exchange::FITKAcousticsVTKCommons::ShapeMeshAbsEnum::MT_Element);
            return m_ids.contains(id);
        }
        case GraphData::DiscNodePick:
        {
            // 仅判断SEA节点是否被拾取过，不区分节点类型。
            id = m_graphObject->getShapeIdByVTKCellId(index, Exchange::FITKAcousticsVTKCommons::ShapeMeshAbsEnum::STA_VERTEX);

            for (const Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode & ssNode : m_seaNodes)
            {
                if (ssNode._id == id)
                {
                    return true;
                }
            }

            return false;
        }
        case GraphData::SEAShellPick:
        case GraphData::SEACavityPick:
        case GraphData::JuncLinePick:
        case GraphData::JuncAreaPick:
        {
            // 合并数据需要单独判断是否拾取到该数据。
            id = m_graphObject->getShapeIdByVTKCellId(index, Exchange::FITKAcousticsVTKCommons::ShapeMeshAbsEnum::STA_SHAPE);
            return m_dataObjId == id;
        }
        case GraphData::SEABeamPick:
        case GraphData::SEASemiInfFluidPick:
        case GraphData::JuncPointPick:
            // 整个数据拾取会在初始Actor判断阶段跳出，无需处理逻辑。
            return true;
        default:
            return false;
        }

        return false;
    }

    bool PickedData::contains(vtkActor2D* actor)
    {
        if (!actor || !m_graphObject)
        {
            return false;
        }

        // 新版本
        //@{
        return m_graphObject->contains(actor);
        //@}
    }

    GUI::GUIPickInfoStru PickedData::getPickedInfo()
    {
        return m_pickedInfo;
    }

    vtkActor* PickedData::getPickedActor()
    {
        return m_pickedActor;
    }

    int PickedData::getPickedIndex()
    {
        return m_pickedIndex;
    }

    PickedMouseType PickedData::getPickedMouseType()
    {
        return m_mouseOper;
    }

    PickedDataType PickedData::getPickedDataType()
    {
        return m_type;
    }

    vtkPlanes* PickedData::getPickPlanes()
    {
        return m_pickPlanes;
    }

    QList<int> & PickedData::getPickedIds()
    {
        return m_ids;
    }

    void PickedData::appendPickedOtherId(int pickId, int pickOtherId)
    {
        m_otherIds.insert(pickId, pickOtherId);
    }

    QHash<int, int> PickedData::getPickedOtherIDs()
    {
        return m_otherIds;
    }

    void PickedData::savePickedDataObjId(int dataObjId)
    {
        m_dataObjId = dataObjId;
    }

    int PickedData::getPickedDataObjId()
    {
        return m_dataObjId;
    }

    QList<Acoustics::FITKAbstractSEASubSysWithNodes::SubSysNode> & PickedData::getPickedDiscNodes()
    {
        // 获取节点列表引用。
        return m_seaNodes;
    }

    QList<PickedFaceData> & PickedData::getPickedSEAFaces()
    {
        // 获取面列表引用。
        return m_seaFaces;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* PickedData::getPickedGraphObejct()
    {
        return m_graphObject;
    }
 
    void PickedData::getPickedWorldPosition(double* pos)
    {
        if (!pos)
        {
            return;
        }

        for (int i = 0; i < 3; i++)
        {
            pos[i] = m_pickedWorldPos[i];
        }
    }
}